package cn.iocoder.yudao.module.scenic.remote.http;

import cn.iocoder.yudao.module.scenic.remote.enums.RemoteResultEnum;
import cn.iocoder.yudao.module.scenic.remote.model.param.common.BodyParam;
import cn.iocoder.yudao.module.scenic.remote.model.param.common.HeadParam;
import cn.iocoder.yudao.module.scenic.remote.model.param.common.QueryParam;
import cn.iocoder.yudao.module.scenic.remote.parser.DefaultParser;
import cn.iocoder.yudao.module.scenic.remote.parser.RemoteResultParser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ArrayUtils;

/**
 * @author superzp
 */
@Slf4j
public class RemoteHelper {


    private static final RemoteResultParser DEFAULT_PARSER = new DefaultParser();


    public static <T> RemoteResult<T> callPost(
            String url,
            HeadParam headParam,
            QueryParam queryParam,
            BodyParam bodyParam,
            Class<T> type, RemoteResultParser... parsers) {
        RemoteResult<T> remoteResult;
        try {

            String json = OkHttpUtils.getInstance().postWithJson(url, headParam, bodyParam, queryParam);
            log.info("返回结果：{}",json);
            // todo 模型接口返回很成问题，每次都不一样，而且不是文档中的json格式
            if(json.indexOf("[")!= 0 &&  json.indexOf("{")>0){
                json = "{\"data\":"+json.substring(json.indexOf("{"))+"}";
                log.info("返回结果replaced：{}",json);
            }else if(json.indexOf("[")==0){
                json = "{\"data\":"+json+"}";
                log.info("返回结果replaced：{}",json);
            }
            RemoteResultParser parser = DEFAULT_PARSER;
            if (parsers != null && !ArrayUtils.isEmpty(parsers)) {
                parser = parsers[0];
            }
            remoteResult = build(json, type, parser);
        } catch (Exception e) {
            log.error("remote call error, url={}, remoteParam={}", url, bodyParam, e);
            remoteResult = RemoteResult.fail(RemoteResultEnum.REMOTE_CALL_FAIL.getCode(), "", "", null);
        }
        return remoteResult;
    }

    public static <T> RemoteResult<T> callPostForm(
            String url,
            HeadParam headParam,
            QueryParam queryParam,
            BodyParam bodyParam,
            Class<T> type, RemoteResultParser... parsers) {
        RemoteResult<T> remoteResult;
        try {

            String json = OkHttpUtils.getInstance().postWithForm(url, headParam, bodyParam,queryParam);
            log.info("返回结果：{}",json);
            RemoteResultParser parser = DEFAULT_PARSER;
            if (parsers != null && !ArrayUtils.isEmpty(parsers)) {
                parser = parsers[0];
            }
            remoteResult = build(json, type, parser);
        } catch (Exception e) {
            log.error("remote call error, url={}, remoteParam={}", url, bodyParam, e);
            remoteResult = RemoteResult.fail(RemoteResultEnum.REMOTE_CALL_FAIL.getCode(), "", "", null);
        }
        return remoteResult;
    }


    public static <T> RemoteResult<T> callGet(
            String url,
            HeadParam headParam,
            QueryParam param,
            Class<T> type, RemoteResultParser... parsers) {
        RemoteResult<T> remoteResult;
        try {

            String json = OkHttpUtils.getInstance().get(url, headParam, param);
            log.info("返回结果：{}",json);
            RemoteResultParser parser = DEFAULT_PARSER;
            if (parsers != null && !ArrayUtils.isEmpty(parsers)) {
                parser = parsers[0];
            }
            remoteResult = build(json, type, parser);
        } catch (Exception e) {
            log.error("remote call error, url={}, remoteParam={}", url, param, e);
            remoteResult = RemoteResult.fail(RemoteResultEnum.REMOTE_CALL_FAIL.getCode(), "", "", null);
        }
        return remoteResult;
    }


    private static <T> RemoteResult<T> build(String json, Class<T> type, RemoteResultParser parser) {

        RemoteResult<T> remoteResult;
        try {
            remoteResult = parser.parse(json, type);
            remoteResult.setSuccess(Boolean.TRUE);
        } catch (Exception e) {
            log.error("Exception error, ", e);
            remoteResult = RemoteResult.fail(RemoteResultEnum.REMOTE_CALL_FAIL.getCode(), "", "", null);
        }
        return remoteResult;
    }






}
